#region license
# This file is part of Grawlix.
# 
# Grawlix is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as
# published by the Free Software Foundation, either version 3 of
# the License, or (at your option) any later version.
# 
# Grawlix is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public
# License along with Grawlix.  If not, see
# <http://www.gnu.org/licenses/>.
#endregion

"""Shared testing objects."""

namespace Grawlix.Meta.Tests.Disposable
import Grawlix.Meta
import System

class NumberArgs(EventArgs):
	[property(Value)]
	private _val as int
	
	def constructor(val as int):
		_val = val

interface IDisposeImpl:
	
	event NumEvent as System.EventHandler[of System.EventArgs]
	
	# Calls NumEvent
	def RaiseEvent(val as int) as void
	
	# Returns x + x
	def Double(x as int) as int
	
	# Throws upon 0, otherwise no
	def No0(x as int) as int
	
	# Initially 15
	Number as int:
		get
	
	# Initially 'hello world!'
	Text as string:
		get
		set
	
class DoFinalizeHelper:
	
	public obj as object
	
	def destructor():
		root = self
		
	public static root as DoFinalizeHelper
	
static class DisposeTests:
	
	def DoFinalize(obj):
	"""May fail with conservative collectors."""
		help = DoFinalizeHelper()
		help.obj = obj
		weakCheck = WeakReference(help, false)
		weakCheck2 = WeakReference(obj, false)
		obj = null
		help = null
		GC.Collect(GC.MaxGeneration)
		GC.WaitForPendingFinalizers()
		expect not weakCheck.IsAlive
		expect not weakCheck2.IsAlive
		expect DoFinalizeHelper.root is not null
		expect DoFinalizeHelper.root.obj is not null
		return DoFinalizeHelper.root.obj
	
	def Integrity(obj):
		impl = obj as IDisposeImpl
		expect impl, _ is not null
		expect impl, _.Number == 15
		expect impl, _.Text == "hello world!"
		expect impl, _.ToString() == "hello world!"
		impl.Text = "goodbye"
		expect impl, _.Text == "goodbye"
		expect impl, _.ToString() == "goodbye"
		expect impl, _.Double(12) == 24
		expect impl, _.No0(12) == 12
		expect ArgumentException:
			impl.No0(0)
		val = 3
		impl.NumEvent += do (sender, args as NumberArgs):
			val = args.Value
		expect val, _ == 3
		impl.RaiseEvent(5)
		expect val, _ == 5
	
	def InvalidUse(obj):
		impl = obj as IDisposeImpl
		expect impl, _ is not null
		expect ObjectDisposedException:
			assert impl.Number == 0
		expect impl, _.ToString() == "[Disposed: " + _.GetType() + "]"
		expect ObjectDisposedException:
			assert impl.Text == null
		expect ObjectDisposedException:
			impl.Text = "goodbye"
		expect ObjectDisposedException:
			assert impl.Double(12) == 0
		expect ObjectDisposedException:
			assert impl.No0(12) == 0
		expect ObjectDisposedException:
			assert impl.No0(0) == 12
		val = 3
		impl.NumEvent += do (sender, args as NumberArgs):
			val = args.Value
		expect val, _ == 3
		expect ObjectDisposedException:
			impl.RaiseEvent(5)
		expect val, _ == 3
	
	def Repeated(obj):
		disp = obj as IDisposable
		for i in range(0, 100):
			disp.Dispose()



